package cn.ctyun.ipush.utils;

import cn.ctyun.ipush.dao.YixinTokenDao;
import cn.ctyun.ipush.model.YixinTokenModel;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: Liu
 * Date: 2016/7/11
 * Time: 19:08
 * To change this template use File | Settings | File Templates..
 */
public class YixinUtils {

    private static final Logger LOG = LoggerFactory.getLogger(YixinUtils.class);

    static public JSONArray jsonArray = new JSONArray();
    static public String refreshToken = new String();
    static public String accessToken = new String();
    static public String refreshTime = new String();
    static public String expiresIn = new String();
    static public YixinTokenModel yixinTokenModelStatic = new YixinTokenModel();
    @Autowired
    protected YixinTokenDao yixinTokenDao;

    @Transactional
    public JSONArray getFriendList(){
        CloseableHttpClient client = HttpClients.createDefault();

        HttpGet get = new HttpGet("https://open.yixin.im/api/friendlist");
        List<NameValuePair> getParameters=new ArrayList<NameValuePair>();
        getParameters.add(new BasicNameValuePair("access_token", accessToken));
        String str = null;
        try {
            str = EntityUtils.toString(new UrlEncodedFormEntity(getParameters,
                    "utf-8"));
        } catch (IOException e) {
//            e.printStackTrace();
            LOG.error("Get Yixin friendList Error:" + e.getMessage());
        }
        try {
            get.setURI(new URI(get.getURI().toString() + "?" + str));
        } catch (URISyntaxException e) {
            e.printStackTrace();
            LOG.error("Get Yixin friendList Error:" + e.getMessage());
        }

        CloseableHttpResponse friendResponse = null;

        try {
            friendResponse = client.execute(get);
        } catch (IOException e) {
//            e.printStackTrace();
            LOG.error("Get Yixin friendList Error:" + e.getMessage());
        }
//        Response res = null;
        String result = null;
        try {
            result = EntityUtils.toString(friendResponse.getEntity());
        } catch (IOException e) {
//            e.printStackTrace();
            LOG.error("Get Yixin friendList Error:" + e.getMessage());
        }

        JSONObject json = new JSONObject();
        JSONObject jsonObject = json.parseObject(result.toString().trim());


        Object friendList = jsonObject.get("friendlist");
        if(friendList != null) {
            JSONArray jsonArray = (JSONArray) friendList;
            return jsonArray;
        }
        else return null;
    }

    public boolean send(List<String> nicks, String img, String url,String title,YixinTokenModel yixinTokenModel){
        try{
//            认证功能无法实现
//            //判断accessToken与refreshToken皆为空时需进行认证
//            if(accessToken.isEmpty() && refreshToken.isEmpty()){
//
//            }
            //调用send方法首先初始化accessToken、refreshToken
//            if(accessToken.isEmpty()&&refreshToken.isEmpty()){
//                initYixinToken(yixinTokenModel);
//            }
            //判断accessToken是否过期
//            SimpleDateFormat formatter;
//            formatter = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss ");
//            java.util.Date create = formatter.parse(refreshTime);
////            boolean isExpired = isExpired(create, Integer.parseInt(expiresIn));
//            if(isExpired){
//                getAccessTokenByRefreshToken("yxbbd0e8b3dce64e02bab42437becc4384", "5a1db5830047b4a", refreshToken);
//            }
           // CloseableHttpClient client = HttpClients.createDefault();

            List<String> accountIds = new ArrayList<String>();
            if (jsonArray==null||jsonArray.isEmpty()){
                jsonArray = getFriendList();
            }
            for(int i = 0; i<jsonArray.size(); i++){
                JSONObject o = (JSONObject) jsonArray.get(i);
                for(String nick:nicks){
                    if(o.get("nick").equals(nick)){
                        accountIds.add(o.get("accountId").toString());
                    }
                }
            }
            if(accountIds.size() == 0){
                jsonArray = getFriendList();
                for(int i = 0; i<jsonArray.size(); i++){
                    JSONObject o = (JSONObject) jsonArray.get(i);
                    for(String nick:nicks){
                        if(o.get("nick").equals(nick)){
                            accountIds.add(o.get("accountId").toString());
                        }
                    }
                }
                if(accountIds.size()==0){
                    LOG.error("未找到易信联系人！");
                    return false;
                }
            }
//        }
            for(String accountId:accountIds){
                CloseableHttpClient client = HttpClients.createDefault();
                HttpPost post = new HttpPost("https://open.yixin.im/api/sendp2pmsg");

                List<NameValuePair> parameters=new ArrayList<NameValuePair>();
                parameters.add(new BasicNameValuePair("access_token", accessToken));
                parameters.add(new BasicNameValuePair("toAccountId", accountId));
                parameters.add(new BasicNameValuePair("content", "{\"image\":\""+ img+"\",\"title\":\""+title+"\",\"url\":\""+url+"\",\"type\":\"image\"}"));

                try {
                    post.setEntity(new UrlEncodedFormEntity(parameters,"UTF-8"));
                } catch (UnsupportedEncodingException e) {
//                e.printStackTrace();
                    LOG.error("Set Yixin Properties Error:" + e.getMessage());
                    return false;
                }

                HttpResponse response= null;
                try {
                    response = client.execute(post);
                    client.close();
                } catch (IOException e) {
                    client.close();
//                .printStackTrace();
                    LOG.error("Get Send Yixin Response Error:" + e.getMessage());
                    return false;
                }

            }

        }catch (Exception e){
            LOG.error("Send Yixin error: " + e.getMessage());
            return false;
        }
        return true;
    }
    //认证获取code
    public String getAuthorize(String appId,String appSecret){
        CloseableHttpClient client = HttpClients.createDefault();

        HttpGet get = new HttpGet("https://open.yixin.im/oauth/authorize");
        List<NameValuePair> getParameters=new ArrayList<NameValuePair>();
        getParameters.add(new BasicNameValuePair("client_id","\""+appId+"\""));
        getParameters.add(new BasicNameValuePair("response_type","code"));
        String str = null;
        try {
            str = EntityUtils.toString(new UrlEncodedFormEntity(getParameters,
                    "utf-8"));
        } catch (IOException e) {
//            e.printStackTrace();
            LOG.error("Get Yixin authorize Error:" + e.getMessage());
        }
        try {
            get.setURI(new URI(get.getURI().toString() + "?" + str));
        } catch (URISyntaxException e) {
            e.printStackTrace();
            LOG.error("Get Yixin friendList Error:" + e.getMessage());
        }

        CloseableHttpResponse authorResponse = null;

        try {
            authorResponse = client.execute(get);
        } catch (IOException e) {
//            e.printStackTrace();
            LOG.error("Get Yixin friendList Error:" + e.getMessage());
        }
//        Response res = null;
        String result = null;
//        String result = null;
        try {
            result = EntityUtils.toString(authorResponse.getEntity());
        } catch (IOException e) {
//            e.printStackTrace();
            LOG.error("Get Yixin accessToken Error:" + e.getMessage());
        }

        JSONObject json = new JSONObject();
        JSONObject jsonObject = json.parseObject(result.toString().trim());
        return  result;
    }
    //根据code获取accessToken
    public String getAccessTokenByCode(String appId,String appSecret,String code){
        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost post = new HttpPost("https://open.yixin.im/oauth/token");

        List<NameValuePair> parameters=new ArrayList<NameValuePair>();
        parameters.add(new BasicNameValuePair("client_id", "\""+appId+"\""));
        parameters.add(new BasicNameValuePair("client_secret", "\""+appSecret+"\""));
        parameters.add(new BasicNameValuePair("grant_type", "authorization_code"));
        parameters.add(new BasicNameValuePair("code","\""+code+"\""));
        try {
            post.setEntity(new UrlEncodedFormEntity(parameters,"UTF-8"));
        } catch (UnsupportedEncodingException e) {
//                e.printStackTrace();
            LOG.error("Set Yixin Properties Error:" + e.getMessage());
        }

        HttpResponse response= null;
        try {
            response = client.execute(post);
        } catch (IOException e) {
//                .printStackTrace();
            LOG.error("Get Send Yixin Response Error:" + e.getMessage());
        }
        String result = null;
        try {
            result = EntityUtils.toString(response.getEntity());
        } catch (IOException e) {
//            e.printStackTrace();
            LOG.error("Get Yixin accessToken Error:" + e.getMessage());
        }

        JSONObject json = new JSONObject();
        JSONObject jsonObject = json.parseObject(result.toString().trim());


        String access_token = jsonObject.get("access_token").toString();
        refreshToken = jsonObject.get("refresh_token").toString();
        String expires_in = jsonObject.get("expores_in").toString();
        LOG.error("accessToke expires in"+ expires_in+"seconds");
        return access_token;

    }
    //根据refreshToken获取accessToken
    public YixinTokenModel getAccessTokenByRefreshToken(String appId,String appSecret,String refreshTokenPara){
        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost post = new HttpPost("https://open.yixin.im/oauth/token");

        List<NameValuePair> parameters=new ArrayList<NameValuePair>();
        parameters.add(new BasicNameValuePair("client_id", appId));
        parameters.add(new BasicNameValuePair("client_secret", appSecret));
        parameters.add(new BasicNameValuePair("grant_type", "refresh_token"));
        parameters.add(new BasicNameValuePair("refresh_token",refreshTokenPara));
        try {
            post.setEntity(new UrlEncodedFormEntity(parameters,"UTF-8"));
        } catch (UnsupportedEncodingException e) {
//                e.printStackTrace();
            LOG.error("Set Yixin Properties Error:" + e.getMessage());
        }

        HttpResponse response= null;
        try {
            response = client.execute(post);
        } catch (IOException e) {
//                .printStackTrace();
            LOG.error("Get Send Yixin Response Error:" + e.getMessage());
        }
        String result = null;
        try {
            result = EntityUtils.toString(response.getEntity());
        } catch (IOException e) {
//            e.printStackTrace();
            LOG.error("Get Yixin accessToken Error:" + e.getMessage());
        }

        JSONObject json = new JSONObject();
        JSONObject jsonObject = json.parseObject(result.toString().trim());


        accessToken = jsonObject.get("access_token").toString();
        refreshToken = jsonObject.get("refresh_token").toString();
        expiresIn = jsonObject.get("expires_in").toString();
        refreshTime = DateUtils.dateToString(new Date());
        YixinTokenModel yixinTokenModel = new YixinTokenModel();
        yixinTokenModel.setYixinTokenModelId("100");
        yixinTokenModel.setAccessToken(accessToken);
        yixinTokenModel.setRefreshToken(refreshToken);
        yixinTokenModel.setExpiresIn(expiresIn);
        yixinTokenModel.setRefreshTime(refreshTime);
//        yixinTokenDao.update(yixinTokenModel);
        LOG.error("accessToke expires in"+ expiresIn+"seconds");
//        return access_token;
        return yixinTokenModel;
    }
    //判断accessToken是否过期
    public boolean isExpired(String createTime,int expireIn) throws ParseException {
//        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        try {
//            Date d1 = df.parse("2004-03-26 13:31:40");
//            Date ima = new Date();
//            long ee = ima.getTime() - d1.getTime();
//            if(expireIn < ee){
//                return true;
//            }
//        } catch (ParseException e) {
//            e.printStackTrace();
//        }
//        Date ima = new Date();
        SimpleDateFormat formatter;
        formatter = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss");
        Date create = formatter.parse(createTime);
        Date now = new Date();
        //若据过期时间小于100秒即重新申请accessToken
        long isExpireding = (expireIn - (now.getTime()-create.getTime())/1000);
        if(isExpireding < 100){
            return true;
        }
        else return false;

    }
    //初始化YixinToken将数据库中数值载入静态变量并判断是否过期如过期修改数据库中保存的值
    public boolean initYixinToken(YixinTokenModel result) throws ParseException {
//        YixinTokenModel yixinTokenModel = new YixinTokenModel();
//        yixinTokenModel.setYixinTokenModelId("100");
//        YixinTokenModel result = yixinTokenDao.querySingleResult("100");
        accessToken = result.getAccessToken();
        refreshToken = result.getRefreshToken();
        refreshTime = result.getRefreshTime();
        expiresIn = result.getExpiresIn();
        boolean isExpired = isExpired(refreshTime,Integer.parseInt(expiresIn));
        if(isExpired){
            yixinTokenModelStatic = getAccessTokenByRefreshToken("yxbbd0e8b3dce64e02bab42437becc4384", "5a1db5830047b4a", refreshToken);
            return true;
        }
        return false;

    }

}
